home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / cp2dekit / samples / loadxm.cpp < prev    next >
C/C++ Source or Header  |  1996-12-29  |  21KB  |  827 lines

  1. //***************************************************************************
  2. //
  3. // this file is (c) '94-'96 Niklas Beisert
  4. //
  5. // this file is part of the cubic player development kit.
  6. // you may only use/modify/spread this file under the terms stated
  7. // in the cubic player development kit accompanying documentation.
  8. //
  9. //***************************************************************************
  10.  
  11.  
  12. //[filetype 10]
  13. //  color=3
  14. //  name=XM
  15. //  interface=_plCubicPlayer
  16. //  player=_gmdPlayer
  17. //  ldlink=loadxm
  18. //  loader=mpLoadXM_
  19.  
  20.  
  21. // loader example
  22.  
  23. #include <string.h>
  24. #include "binfile.h"
  25.  
  26. #include "mcp.h"
  27. #include "mp.h"
  28. #include "err.h"
  29.  
  30. static inline void putcmd(unsigned char *&p, unsigned char c, unsigned char d)
  31. {
  32.   *p++=c;
  33.   *p++=d;
  34. }
  35.  
  36. static inline void advancenote(unsigned char *&x)
  37. {
  38.   unsigned char s=*x;
  39.   if (s&0x80)
  40.   {
  41.     x++;
  42.     if (s&1)
  43.       x++;
  44.     if (s&2)
  45.       x++;
  46.     if (s&4)
  47.       x++;
  48.     if (s&8)
  49.       x++;
  50.     if (s&16)
  51.       x++;
  52.   }
  53.   else
  54.     x+=5;
  55. }
  56.  
  57. extern "C" int mpLoadXM(module &m, binfile &file)
  58. {
  59.   m.reset();
  60.  
  61.   struct
  62.   {
  63.     char sig[17];
  64.     char name[20];
  65.     char whythis1a;
  66.     char tracker[20];
  67.     unsigned short ver;
  68.     unsigned long hdrsize;
  69.   } head1;
  70.  
  71.   struct
  72.   {
  73.     unsigned short ordnum;
  74.     unsigned short restart;
  75.     unsigned short channum;
  76.     unsigned short patnum;
  77.     unsigned short insnum;
  78.     unsigned short freqtab;
  79.     unsigned short tempo;
  80.     unsigned short speed;
  81.     unsigned char ord[256];
  82.   } head2;
  83.  
  84.   file.read(&head1, sizeof(head1));
  85.   if (memcmp(head1.sig, "Extended Module: ", 17))
  86.     return errFormSig;
  87.   if (head1.whythis1a!=26)
  88.     return errFormStruc;
  89.   if (head1.ver<0x104)
  90.     return errFormOldVer;
  91.   file.read(&head2, sizeof(head2));
  92.   file.seekcur(head1.hdrsize-4-sizeof(head2));
  93.  
  94.   if (!head2.insnum)
  95.     return errFormMiss;
  96.  
  97.   memcpy(m.name, head1.name, 20);
  98.   m.name[20]=0;
  99.  
  100.   m.options=(head2.freqtab&1)?MOD_EXPOFREQ:0;
  101.   m.channum=head2.channum;
  102.   m.instnum=head2.insnum;
  103.   m.envnum=head2.insnum*2;
  104.   m.patnum=head2.patnum+1;
  105.   m.ordnum=head2.ordnum;
  106.   m.endord=m.ordnum;
  107.   m.tracknum=(head2.channum+1)*head2.patnum+1;
  108.   m.loopord=head2.restart;
  109.  
  110.   sampleinfo **smps=new sampleinfo *[m.instnum];
  111.   sample **msmps=new sample *[m.instnum];
  112.   int *instsmpnum=new int [m.instnum];
  113.   if (!instsmpnum||!m.allocinstruments()||!m.allocpatterns()||!m.alloctracks()||!m.allocenvelopes()||!smps||!msmps||!m.allocorders())
  114.     return errAllocMem;
  115.  
  116.   int i,t,j;
  117.  
  118.   for (i=0; i<m.ordnum; i++)
  119.     m.orders[i]=(head2.ord[i]<head2.patnum)?head2.ord[i]:head2.patnum;
  120.  
  121.   for (i=0; i<m.channum; i++)
  122.     m.patterns[head2.patnum].tracks[i]=m.tracknum-1;
  123.   m.patterns[head2.patnum].gtrack=m.tracknum-1;
  124.   m.patterns[head2.patnum].patlen=64;
  125.  
  126.   unsigned char *temptrack=new unsigned char[3000];
  127.   unsigned short buflen=2048;
  128.   unsigned char *buffer=new unsigned char[buflen];
  129.   if (!buffer||!temptrack)
  130.     return errAllocMem;
  131.  
  132.   for (t=0; t<head2.patnum; t++)
  133.   {
  134.     struct
  135.     {
  136.       unsigned long len;
  137.       unsigned char ptype;
  138.       unsigned short rows;
  139.       unsigned short patdata;
  140.     } pathead;
  141.     file.read(&pathead, sizeof(pathead));
  142.     file.seekcur(pathead.len-sizeof(pathead));
  143.  
  144.     pattern &pp=m.patterns[t];
  145.     for (i=0; i<m.channum; i++)
  146.       pp.tracks[i]=t*(m.channum+1)+i;
  147.     pp.gtrack=t*(m.channum+1)+m.channum;
  148.     pp.patlen=pathead.rows;
  149.  
  150.     int clean=0;
  151.     if (pathead.patdata==0)
  152.     {
  153.       clean=1;
  154.       pathead.patdata=m.channum*pathead.rows;
  155.     }
  156.  
  157.     if (pathead.patdata>buflen)
  158.     {
  159.       buflen=pathead.patdata;
  160.       delete buffer;
  161.       buffer=new unsigned char[buflen];
  162.       if (!buffer)
  163.         return errAllocMem;
  164.     }
  165.     if (clean)
  166.       memset(buffer, 0x80, pathead.patdata);
  167.     else
  168.       file.read(buffer, pathead.patdata);
  169.  
  170.     for (i=0; i<m.channum; i++)
  171.     {
  172.       unsigned char *tp=temptrack;
  173.       unsigned char *buf=buffer;
  174.  
  175.       char xxq;
  176.       for (xxq=0; xxq<i; xxq++)
  177.         advancenote(buf);
  178.  
  179.       unsigned short row;
  180.       for (row=0; row<pathead.rows; row++)
  181.       {
  182.         unsigned char *cp=tp+2;
  183.  
  184.         signed short nte=-1;
  185.         unsigned char vol=0;
  186.         signed short pan=-1;
  187.         signed short volv=-1;
  188.         signed short ins=-1;
  189.         unsigned char command=0;
  190.         unsigned char data=0;
  191.  
  192.         unsigned char x=0x1F;
  193.         if (*buf&0x80)
  194.           x=*buf++&~0x80;
  195.         if (x&1)
  196.         {
  197.           nte=11+(*buf++&~0x80);
  198.           if (nte==11)  // ???
  199.             nte=-1;
  200.         }
  201.         if (x&2)
  202.           ins=*buf++-1;
  203.         if (x&4)
  204.           vol=*buf++;
  205.         if (x&8)
  206.           command=*buf++;
  207.         if (x&16)
  208.           data=*buf++;
  209.         if (row!=(pathead.rows-1))
  210.           for (xxq=0; xxq<(m.channum-1); xxq++)
  211.             advancenote(buf);
  212.  
  213.         if ((vol>=0x10)&&(vol<=0x50))
  214.           volv=vol-0x10;
  215.  
  216.         if (command==0xC)
  217.           volv=data;
  218.  
  219.         if ((vol&0xF0)==0xC0)
  220.           pan=(vol&0xF)+((vol&0xF)<<4);
  221.  
  222.         if (command==0x8)
  223.           pan=data;
  224.  
  225.         if ((command==0xE)&&((data&0xF0)==0x80))
  226.           pan=(data&0xF)+((data&0xF)<<4);
  227.  
  228.         if (((command==0x3)||(command==0x5)||((vol&0xF0)==0xF0))&&(nte!=-1)&&(nte!=108))
  229.           nte|=128;
  230.  
  231.         if ((ins!=-1)||(nte!=-1)||(volv!=-1)||(pan!=-1))
  232.         {
  233.           if (nte==108)
  234.           {
  235.             putcmd(cp, cmdKeyOff, 0);
  236.             nte=-1;
  237.           }
  238.           unsigned char &act=*cp;
  239.           *cp++=cmdPlayNote;
  240.           if (ins!=-1)
  241.           {
  242.             act|=cmdPlayIns;
  243.             *cp++=ins;
  244.           }
  245.           if (nte!=-1)
  246.           {
  247.             act|=cmdPlayNte;
  248.             *cp++=nte;
  249.           }
  250.           if (volv!=-1)
  251.           {
  252.             act|=cmdPlayVol;
  253.             *cp++=(volv==0x40)?0xFF:(volv<<2);
  254.           }
  255.           if (pan!=-1)
  256.           {
  257.             act|=cmdPlayPan;
  258.             *cp++=pan;
  259.           }
  260.           if ((command==0xE)&&((data>>4)==0xD))
  261.           {
  262.             act|=cmdPlayDelay;
  263.             *cp++=data&0xF;
  264.           }
  265.         }
  266.  
  267.         if ((vol&0xF0)==0x60)
  268.           if (vol&0xF)
  269.             putcmd(cp, cmdVolSlideDown, (vol&0x0F)<<2);
  270.  
  271.         if ((vol&0xF0)==0x70)
  272.           if (vol&0xF)
  273.             putcmd(cp, cmdVolSlideUp, (vol&0x0F)<<2);
  274.  
  275.         if ((vol&0xF0)==0x80)
  276.           if (vol&0xF)
  277.             putcmd(cp, cmdRowVolSlideDown, (vol&0x0F)<<2);
  278.  
  279.         if ((vol&0xF0)==0x90)
  280.           if (vol&0xF)
  281.             putcmd(cp, cmdRowVolSlideUp, (vol&0x0F)<<2);
  282.  
  283.         if ((vol&0xF0)==0xA0)
  284.           putcmd(cp, cmdPitchVibratoSetSpeed, vol&0x0F);
  285.  
  286.         if ((vol&0xF0)==0xB0)
  287.           putcmd(cp, cmdPitchVibrato, (vol&0x0F)<<4);
  288.  
  289.         if ((vol&0xF0)==0xD0)
  290.           if (vol&0xF)
  291.             putcmd(cp, cmdPanSlide, -(vol&0x0F));
  292.  
  293.         if ((vol&0xF0)==0xE0)
  294.           if (vol&0xF)
  295.             putcmd(cp, cmdPanSlide, vol&0x0F);
  296.  
  297.         if ((vol&0xFFF0)==0xF0)
  298.           putcmd(cp, cmdPitchSlideToNote, (vol&0x0F)<<4);
  299.  
  300.         switch (command)
  301.         {
  302.         case 0x0:
  303.           if (data)
  304.             putcmd(cp, cmdArpeggio, data);
  305.           break;
  306.         case 0x1:
  307.           putcmd(cp, cmdPitchSlideUp, data);
  308.           break;
  309.         case 0x2:
  310.           putcmd(cp, cmdPitchSlideDown, data);
  311.           break;
  312.         case 0x3:
  313.           putcmd(cp, cmdPitchSlideToNote, data);
  314.           break;
  315.         case 0x4:
  316.           putcmd(cp, cmdPitchVibrato, data);
  317.           break;
  318.         case 0x5:
  319.           putcmd(cp, cmdPitchSlideToNote, 0);
  320.           if (!data)
  321.             putcmd(cp, cmdSpecial, cmdContVolSlide);
  322.           else
  323.           if (data&0xF0)
  324.             putcmd(cp, cmdVolSlideUp, (data>>4)<<2);
  325.           else
  326.             putcmd(cp, cmdVolSlideDown, (data&0xF)<<2);
  327.           break;
  328.         case 0x6:
  329.           putcmd(cp, cmdPitchVibrato, 0);
  330.           if (!data)
  331.             putcmd(cp, cmdSpecial, cmdContVolSlide);
  332.           else
  333.           if (data&0xF0)
  334.             putcmd(cp, cmdVolSlideUp, (data>>4)<<2);
  335.           else
  336.             putcmd(cp, cmdVolSlideDown, (data&0xF)<<2);
  337.           break;
  338.         case 0x7:
  339.           putcmd(cp, cmdVolVibrato, data);
  340.           break;
  341.         case 0x9:
  342.           if (nte!=-1)
  343.             putcmd(cp, cmdOffset, data);
  344.           break;
  345.         case 0xA:
  346.           if (!data)
  347.             putcmd(cp, cmdSpecial, cmdContVolSlide);
  348.           else
  349.           if (data&0xF0)
  350.             putcmd(cp, cmdVolSlideUp, (data>>4)<<2);
  351.           else
  352.             putcmd(cp, cmdVolSlideDown, (data&0xF)<<2);
  353.           break;
  354.         case 0xE:
  355.           command=data>>4;
  356.           data&=0xF;
  357.           switch (command)
  358.           {
  359.           case 0x1:
  360.             putcmd(cp, cmdRowPitchSlideUp, data<<4);
  361.             break;
  362.           case 0x2:
  363.             putcmd(cp, cmdRowPitchSlideDown, data<<4);
  364.             break;
  365.           case 0x3:
  366.             putcmd(cp, cmdSpecial, data?cmdGlissOn:cmdGlissOff);
  367.             break;
  368.           case 0x4:
  369.             if (data<4)
  370.               putcmd(cp, cmdPitchVibratoSetWave, data);
  371.             break;
  372.           case 0x7:
  373.             if (data<4)
  374.               putcmd(cp, cmdVolVibratoSetWave, data);
  375.             break;
  376.           case 0x9:
  377.             if (data)
  378.               putcmd(cp, cmdRetrig, data);
  379.         break;
  380.           case 0xA:
  381.         putcmd(cp, cmdRowVolSlideUp, data<<2);
  382.             break;
  383.           case 0xB:
  384.             putcmd(cp, cmdRowVolSlideDown, data<<2);
  385.             break;
  386.           case 0xC:
  387.             putcmd(cp, cmdNoteCut, data);
  388.         break;
  389.           }
  390.           break;
  391.         case 0x14:
  392.           putcmd(cp, cmdKeyOff, 0);
  393.           break;
  394.         case 0x15:
  395.           if (data)
  396.             putcmd(cp, cmdSetEnvPos, data);
  397.           break;
  398.         case 0x19:
  399.           if (!data)
  400.             putcmd(cp, cmdPanSlide, 0);
  401.           else
  402.           if (data&0xF0)
  403.             putcmd(cp, cmdPanSlide, data>>4);
  404.           else
  405.             putcmd(cp, cmdPanSlide, -(data&0xF));
  406.           break;
  407.         case 0x1B:
  408.           putcmd(cp, cmdRetrig, data);
  409.           break;
  410.         case 0x1D:
  411.           putcmd(cp, cmdTremor, data);
  412.           break;
  413.         case 0x21:
  414.           if ((data&0xF0)==0x10)
  415.             putcmd(cp, cmdRowPitchSlideUp, (data&0xF)<<2);
  416.           else
  417.           if ((data&0xF0)==0x20)
  418.             putcmd(cp, cmdRowPitchSlideDown, (data&0xF)<<2);
  419.           break;
  420.         case 0x22:
  421.           putcmd(cp, cmdPanHeight, (data>>4)*0x11);
  422.           putcmd(cp, cmdPanDepth, (data&0xF)*0x11);
  423.           break;
  424.         }
  425.  
  426.         if (cp!=(tp+2))
  427.         {
  428.           tp[0]=row;
  429.           tp[1]=cp-tp-2;
  430.           tp=cp;
  431.         }
  432.       }
  433.  
  434.       track &trk=m.tracks[t*(m.channum+1)+i];
  435.       unsigned short len=tp-temptrack;
  436.  
  437.       if (!len)
  438.         trk.ptr=trk.end=0;
  439.       else
  440.       {
  441.         trk.ptr=new unsigned char[len];
  442.         trk.end=trk.ptr+len;
  443.         if (!trk.ptr)
  444.           return errAllocMem;
  445.         memcpy(trk.ptr, temptrack, len);
  446.       }
  447.     }
  448.  
  449.     unsigned char *tp=temptrack;
  450.     unsigned char *buf=buffer;
  451.  
  452.     unsigned short row, q;
  453.     for (row=0; row<pathead.rows; row++)
  454.     {
  455.       unsigned char *cp=tp+2;
  456.       if (!row&&(t==head2.ord[0]))
  457.       {
  458.         if (head2.tempo!=6)
  459.          putcmd(cp, cmdTempo, head2.tempo);
  460.         if (head2.speed!=125)
  461.          putcmd(cp, cmdSpeed, head2.speed);
  462.       }
  463.       for (q=0; q<m.channum; q++)
  464.       {
  465.         unsigned char x=0x1F;
  466.         if (*buf&0x80)
  467.           x=*buf++&~0x80;
  468.  
  469.         signed short command=-1;
  470.         unsigned char data=0;
  471.  
  472.         if (x&1)
  473.           buf++;
  474.         if (x&2)
  475.           buf++;
  476.         if (x&4)
  477.           buf++;
  478.         if (x&8)
  479.           command=*buf++;
  480.         if (x&16)
  481.           data=*buf++;
  482.  
  483.         switch (command)
  484.         {
  485.         case 0xB:
  486.           putcmd(cp, cmdGoto, data);
  487.           break;
  488.         case 0xD:
  489.           putcmd(cp, cmdBreak, (data&0x0F)+(data>>4)*10);
  490.           break;
  491.         case 0xE:
  492.           switch (data>>4)
  493.           {
  494.           case 0x6:
  495.             putcmd(cp, cmdSetChan, q);
  496.             putcmd(cp, cmdPatLoop, data&0xF);
  497.             break;
  498.           case 0xE:
  499.             putcmd(cp, cmdPatDelay, data&0xF);
  500.             break;
  501.           }
  502.           break;
  503.         case 0xF:
  504.           if (data)
  505.             if (data<0x20)
  506.               putcmd(cp, cmdTempo, data);
  507.             else
  508.               putcmd(cp, cmdSpeed, data);
  509.           else
  510.             putcmd(cp, cmdGoto, 0);
  511.           break;
  512.         case 0x10:
  513.           putcmd(cp, cmdGlobVol, (data>0x3F)?0xFF:(data<<2));
  514.           break;
  515.         case 0x11:
  516.           if ((data&0x0F)&&(data&0xF0))
  517.             break;
  518.           putcmd(cp, cmdSetChan, q);
  519.           if (data&0xF0)
  520.             putcmd(cp, cmdGlobVolSlide, (data>>4)<<2);
  521.           else
  522.             putcmd(cp, cmdGlobVolSlide, -((data&0xF)<<2));
  523.         }
  524.       }
  525.       if (cp!=(tp+2))
  526.       {
  527.         tp[0]=row;
  528.         tp[1]=cp-tp-2;
  529.         tp=cp;
  530.       }
  531.     }
  532.  
  533.     track &trk=m.tracks[t*(m.channum+1)+m.channum];
  534.     unsigned short len=tp-temptrack;
  535.  
  536.     if (!len)
  537.       trk.ptr=trk.end=0;
  538.     else
  539.     {
  540.       trk.ptr=new unsigned char[len];
  541.       trk.end=trk.ptr+len;
  542.       if (!trk.ptr)
  543.         return errAllocMem;
  544.       memcpy(trk.ptr, temptrack, len);
  545.     }
  546.   }
  547.  
  548.   delete temptrack;
  549.   delete buffer;
  550.  
  551.   m.sampnum=0;
  552.   m.modsampnum=0;
  553.   for (i=0; i<m.instnum; i++)
  554.   {
  555.     instrument &ip=m.instruments[i];
  556.     envelope *env=m.envelopes+2*i;
  557.     smps[i]=0;
  558.     msmps[i]=0;
  559.     struct
  560.     {
  561.       unsigned long size;
  562.       char name[22];
  563.       char type;
  564.       unsigned short samp;
  565.     } ins1;
  566.     file.read(&ins1, sizeof(ins1));
  567.     memcpy(ip.name, ins1.name, 22);
  568.     ip.name[22]=0;
  569.     instsmpnum[i]=ins1.samp;
  570.     if (!ins1.samp)
  571.     {
  572.       file.seekcur(ins1.size-sizeof(ins1));
  573.       continue;
  574.     }
  575.     struct
  576.     {
  577.       unsigned long shsize;
  578.       unsigned char snum[96];
  579.       unsigned short venv[12][2];
  580.       unsigned short penv[12][2];
  581.       unsigned char vnum, pnum;
  582.       unsigned char vsustain, vloops, vloope, psustain, ploops, ploope;
  583.       unsigned char vtype, ptype;
  584.       unsigned char vibtype, vibsweep, vibdepth, vibrate;
  585.       unsigned short volfade;
  586.       unsigned short res;
  587.     } ins2;
  588.     file.read(&ins2, sizeof(ins2));
  589.     file.seekcur(ins1.size-sizeof(ins1)-sizeof(ins2));
  590.  
  591.     smps[i]=new sampleinfo[ins1.samp];
  592.     msmps[i]=new sample[ins1.samp];
  593.     if (!ip.samples||!smps[i]||!msmps[i])
  594.       return errAllocMem;
  595.     memset(msmps[i], 0, sizeof(**msmps)*ins1.samp);
  596.     memset(smps[i], 0, sizeof(**smps)*ins1.samp);
  597.  
  598.     for (j=0; j<96; j++)
  599.       if (ins2.snum[j]<ins1.samp)
  600.         ip.samples[j+12]=m.modsampnum+ins2.snum[j];
  601.     unsigned short volfade=0xFFFF;
  602.     if (ins2.vtype&1)
  603.     {
  604.       volfade=ins2.volfade;
  605.       env[0].speed=0;
  606.       env[0].type=0;
  607.       env[0].env=new unsigned char[ins2.venv[ins2.vnum-1][0]+1];
  608.       if (!env[0].env)
  609.         return errAllocMem;
  610.       short k, p=0, h=ins2.venv[0][1]*4;
  611.       for (j=1; j<ins2.vnum; j++)
  612.       {
  613.         short l=ins2.venv[j][0]-p;
  614.         short dh=ins2.venv[j][1]*4-h;
  615.         for (k=0; k<l; k++)
  616.         {
  617.           short cv=h+dh*k/l;
  618.           env[0].env[p++]=(cv>255)?255:cv;
  619.         }
  620.         h+=dh;
  621.       }
  622.       env[0].len=p;
  623.       env[0].env[p]=(h>255)?255:h;
  624.       if (ins2.vtype&2)
  625.       {
  626.         env[0].type|=mpEnvSLoop;
  627.         if (!(ins2.vtype&4)||(ins2.vsustain<=ins2.vloope))
  628.         {
  629.           env[0].sloops=ins2.venv[ins2.vsustain][0];
  630.           env[0].sloope=ins2.venv[ins2.vsustain][0]+1;
  631.         }
  632.         else
  633.         {
  634.           env[0].sloops=ins2.venv[ins2.vloops][0];
  635.           env[0].sloope=ins2.venv[ins2.vloope][0];
  636.         }
  637.       }
  638.       if (ins2.vtype&4)
  639.       {
  640.         if ((ins2.vtype&2)&&(ins2.vsustain==ins2.vloope))
  641.         {
  642.           env[0].type|=mpEnvSLoop;
  643.           env[0].sloops=ins2.venv[ins2.vloops][0];
  644.           env[0].sloope=ins2.venv[ins2.vloope][0];
  645.         }
  646.         else
  647.         {
  648.           env[0].type|=mpEnvLoop;
  649.           env[0].loops=ins2.venv[ins2.vloops][0];
  650.           env[0].loope=ins2.venv[ins2.vloope][0];
  651.         }
  652.       }
  653.     }
  654.     if (ins2.ptype&1)
  655.     {
  656.       env[1].speed=0;
  657.       env[1].type=0;
  658.       env[1].env=new unsigned char[ins2.penv[ins2.pnum-1][0]+1];
  659.       if (!env[1].env)
  660.         return errAllocMem;
  661.       short k, p=0, h=ins2.penv[0][1]*4;
  662.       for (j=1; j<ins2.pnum; j++)
  663.       {
  664.         short l=ins2.penv[j][0]-p;
  665.         short dh=ins2.penv[j][1]*4-h;
  666.         for (k=0; k<l; k++)
  667.         {
  668.           short cv=h+dh*k/l;
  669.           env[1].env[p++]=(cv>255)?255:cv;
  670.         }
  671.         h+=dh;
  672.       }
  673.       env[1].len=p;
  674.       env[1].env[p]=(h>255)?255:h;
  675.       if (ins2.ptype&2)
  676.       {
  677.         env[1].type|=mpEnvSLoop;
  678.         if (!(ins2.ptype&4)||(ins2.psustain<=ins2.ploope))
  679.         {
  680.           env[1].sloops=ins2.penv[ins2.psustain][0];
  681.           env[1].sloope=ins2.penv[ins2.psustain][0]+1;
  682.         }
  683.         else
  684.         {
  685.           env[1].sloops=ins2.penv[ins2.ploops][0];
  686.           env[1].sloope=ins2.penv[ins2.ploope][0];
  687.         }
  688.       }
  689.       if (ins2.ptype&4)
  690.       {
  691.         if ((ins2.ptype&2)&&(ins2.psustain==ins2.ploope))
  692.         {
  693.           env[1].type|=mpEnvSLoop;
  694.           env[1].sloops=ins2.penv[ins2.ploops][0];
  695.           env[1].sloope=ins2.penv[ins2.ploope][0];
  696.         }
  697.         else
  698.         {
  699.           env[1].type|=mpEnvLoop;
  700.           env[1].loops=ins2.penv[ins2.ploops][0];
  701.           env[1].loope=ins2.penv[ins2.ploope][0];
  702.         }
  703.       }
  704.     }
  705. /*
  706.     unsigned char pchsweep;
  707.     if (ins2.vibdepth&&ins2.vibrate)
  708.     {
  709.       env[2].speed=0;
  710.       env[2].opt=0;
  711.       env[2].len=256;
  712.       env[2].sustain=-1;
  713.       env[2].loops=0;
  714.       env[2].loope=256;
  715.       env[2].env=new unsigned char [256];
  716.       if (!env[2].env)
  717.         return errAllocMem;
  718.       unsigned char ph=0;
  719.       for (j=0; j<256; j++)
  720.       {
  721.         ph+=ins2.vibrate;
  722.         switch (ins2.vibtype)
  723.         {
  724.         case 0:
  725.           env[2].env[j]=128+((ins2.vibdepth*vibsintab[ph])>>10);
  726.           break;
  727.         case 1:
  728.           env[2].env[j]=128+((ins2.vibdepth*(64-(ph&128)))>>5);
  729.           break;
  730.         case 2:
  731.           env[2].env[j]=128+((ins2.vibdepth*(128-ph))>>6);
  732.           break;
  733.         case 3:
  734.           env[2].env[j]=128+((ins2.vibdepth*(ph-128))>>6);
  735.           break;
  736.         }
  737.       }
  738.     }
  739. */
  740.     for (j=0; j<ins1.samp; j++)
  741.     {
  742.       struct
  743.       {
  744.         unsigned long samplen;
  745.         unsigned long loopstart;
  746.         unsigned long looplen;
  747.         unsigned char vol;
  748.         signed char finetune;
  749.         unsigned char type;
  750.         unsigned char pan;
  751.         signed char relnote;
  752.         unsigned char res;
  753.         unsigned char name[22];
  754.       } samp;
  755.       file.read(&samp, sizeof (samp));
  756.       file.seekcur(ins2.shsize-sizeof(samp));
  757.       if (samp.type&16)
  758.       {
  759.         samp.samplen>>=1;
  760.         samp.loopstart>>=1;
  761.         samp.looplen>>=1;
  762.       }
  763.  
  764.       sample &sp=msmps[i][j];
  765.       memcpy(sp.name, samp.name, 22);
  766.       sp.name[22]=0;
  767.       sp.handle=0xFFFF;
  768.       sp.normnote=-samp.relnote*256-samp.finetune*2;
  769.       sp.stdvol=(samp.vol>0x3F)?0xFF:(samp.vol<<2);
  770.       sp.stdpan=samp.pan;
  771.       sp.opt=0;
  772.       sp.volfade=volfade;
  773.       sp.vibtype=ins2.vibtype;
  774.       sp.vibdepth=ins2.vibdepth<<2;
  775.       sp.vibspeed=0;
  776.       sp.vibrate=ins2.vibrate<<8;
  777.       sp.vibsweep=0xFFFF/(ins2.vibsweep+1);
  778.       sp.volenv=env[0].env?(2*i+0):0xFFFF;
  779.       sp.panenv=env[1].env?(2*i+1):0xFFFF;
  780.       sp.pchenv=0xFFFF;
  781.  
  782.       sampleinfo &sip=smps[i][j];
  783.       sip.length=samp.samplen;
  784.       sip.loopstart=samp.loopstart;
  785.       sip.loopend=samp.loopstart+samp.looplen;
  786.       sip.samprate=8363;
  787.       sip.type=mcpSampDelta|((samp.type&16)?mcpSamp16Bit:0)|((samp.type&3)?(((samp.type&3)==2)?(mcpSampLoop|mcpSampBiDi):mcpSampLoop):0);
  788.     }
  789.     for (j=0; j<ins1.samp; j++)
  790.     {
  791.       sample &sp=msmps[i][j];
  792.       sampleinfo &sip=smps[i][j];
  793.       unsigned long l=sip.length<<(!!(sip.type&mcpSamp16Bit));
  794.       if (!l)
  795.         continue;
  796.       sip.ptr=new char [l+16];
  797.       if (!sip.ptr)
  798.         return errAllocMem;
  799.       file.read(sip.ptr, l);
  800.       sp.handle=m.sampnum+j;
  801.     }
  802.     m.sampnum+=ins1.samp;
  803.     m.modsampnum+=ins1.samp;
  804.   }
  805.  
  806.   if (!m.allocsamples()||!m.allocmodsamples())
  807.     return errAllocMem;
  808.  
  809.   m.sampnum=0;
  810.   m.modsampnum=0;
  811.   for (i=0; i<m.instnum; i++)
  812.   {
  813.     for (j=0; j<instsmpnum[i]; j++)
  814.     {
  815.       m.samples[m.sampnum++]=smps[i][j];
  816.       m.modsamples[m.modsampnum++]=msmps[i][j];
  817.     }
  818.     delete smps[i];
  819.     delete msmps[i];
  820.   }
  821.   delete smps;
  822.   delete msmps;
  823.   delete instsmpnum;
  824.  
  825.   return errOk;
  826. }
  827.